package io.github.libkodi.vertxauth.data;

import java.io.BufferedInputStream;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;
import java.util.HashMap;

import io.github.libkodi.basic_gateway.context.Context;
import io.vertx.core.Future;
import io.vertx.redis.client.Command;
import io.vertx.redis.client.Redis;
import io.vertx.redis.client.RedisAPI;
import io.vertx.redis.client.RedisConnection;
import io.vertx.redis.client.Request;
import io.vertx.redis.client.Response;
import io.vertx.redis.client.ResponseType;

public class AuthDataCenter {
	private Context ctx = null;
	private Redis redis = null;
	private String redisSuffix = "";
	private HashMap<String, ExpireData> data = new HashMap<String, ExpireData>();
	
	public AuthDataCenter(Redis redis) {
		this.redis = redis;
	}
	
	public AuthDataCenter(Redis redis, String suffix) {
		this.redis = redis;
		this.redisSuffix  = suffix != null ? suffix : "";
	}
	
	public AuthDataCenter(Context ctx) {
		this.ctx = ctx;
		this.init();
	}

	public void _setContext(Context context) {
		ctx = context;
		this.init();
	}

	private void init() {
		
	}
	
	public Future<Void> setValue(String key, Object value) {
		return Future.future(promise -> {
			if (redis == null) {
				if (data.containsKey(key)) {
					data.get(key).setValue(value);
				} else {
					data.put(key, new ExpireData(value));
				}
				
				promise.complete();
			} else {
				command(Command.SET, redisSuffix + key, value).onSuccess(resp -> {
					promise.complete();
				}).onFailure(promise::fail);
			}
		});
	}

	private Future<Response> command(Command command, Object... args) {
		return Future.future(promise -> {
			if (redis != null) {
				redis.connect().onSuccess(conn -> {
					conn.send(Request.cmd(command, args)).onSuccess(resp -> {
						promise.complete(resp);
						conn.close();
					}).onFailure(e -> {
						conn.close();
						promise.fail(e);
					});
				}).onFailure(promise::fail);
			} else {
				promise.complete(null);
			}
		});
	}

}
